﻿using System;
using System.Collections.Generic;
using System.Text;

namespace Framework.Message.SMS.CommonLibrary.Generic
{
    public abstract class BaseCommand<CommandT, SequenceT, HeaderT> where HeaderT : BaseCommandHeader<CommandT, SequenceT>
    {
        private HeaderT _Header;

        public HeaderT Header
        {
            get { return _Header; }
            set { _Header = value; }
        }

        public abstract CommandT CommandType { get; }

        public abstract uint BodyLength { get; }

        public BaseCommand()
        {
            this._Header = CreateHeader(CommandType, default(SequenceT));
        }

        public BaseCommand(byte[] bytes)
        {
            this.BytesTo(bytes, 0);
        }

        public BaseCommand(byte[] bytes, int startIndex)
        {
            this.BytesTo(bytes, startIndex);
        }

        public BaseCommand(SequenceT sequence)
        {
            this._Header = CreateHeader(CommandType, sequence);
        }

        protected abstract HeaderT CreateHeader(CommandT commandType, SequenceT sequence);

        protected abstract HeaderT CreateHeader(byte[] bytes, int startIndex);

        protected virtual void BytesTo(byte[] bytes, int startIndex)
        {
            if (CheckCommandType(bytes, startIndex))
            {
                this._Header = CreateHeader(bytes, startIndex);
            }
        }

        public virtual byte[] ToBytes()
        {
            byte[] bytes = new byte[this.Header.MessageLength];
            Header.ToBytes().CopyTo(bytes, 0);
            return bytes;
        }

        public abstract bool CheckCommandType(byte[] bytes, int startIndex);

        public bool CheckCommandType(byte[] bytes)
        {
            return this.CheckCommandType(bytes, 0);
        }
    }
}
